# Slice and Dice လုပ်ဖို့ အချိန်တန်ပြီ[[time-to-slice-and-dice]]

<CourseFloatingBanner chapter={5}
  classNames="absolute z-10 right-0 top-0"
  notebooks={[
    {label: "Google Colab", value: "https://colab.research.google.com/github/huggingface/notebooks/blob/master/course/en/chapter5/section3.ipynb"},
    {label: "Aws Studio", value: "https://studiolab.sagemaker.aws/import/github/huggingface/notebooks/blob/master/course/en/chapter5/section3.ipynb"},
]} />

အများအားဖြင့်၊ သင်အလုပ်လုပ်တဲ့ data တွေက models တွေကို train လုပ်ဖို့အတွက် ပြီးပြည့်စုံစွာ ပြင်ဆင်ထားမှာ မဟုတ်ပါဘူး။ ဒီအပိုင်းမှာ 🤗 Datasets က သင့် datasets တွေကို သန့်ရှင်းရေးလုပ်ဖို့ ပံ့ပိုးပေးတဲ့ features အမျိုးမျိုးကို ကျွန်တော်တို့ လေ့လာသွားမှာပါ။

<Youtube id="tqfSFcPMgOI"/>

## ကျွန်တော်တို့ရဲ့ Data ကို Slicing and Dicing လုပ်ခြင်း[[slicing-and-dicing-our-data]]

Pandas နဲ့ ဆင်တူစွာ၊ 🤗 Datasets က `Dataset` နဲ့ `DatasetDict` objects တွေရဲ့ အကြောင်းအရာတွေကို ခြယ်လှယ်ဖို့ functions အမျိုးမျိုးကို ပံ့ပိုးပေးပါတယ်။ [Chapter 3](/course/chapter3) မှာ `Dataset.map()` method ကို ကျွန်တော်တို့ ကြုံတွေ့ခဲ့ရပြီးပါပြီ၊ ဒီအပိုင်းမှာတော့ ကျွန်တော်တို့ ရရှိနိုင်တဲ့ အခြား functions အချို့ကို လေ့လာသွားမှာပါ။

ဒီဥပမာအတွက် [UC Irvine Machine Learning Repository](https://archive.ics.uci.edu/ml/index.php) မှာ host လုပ်ထားတဲ့ [Drug Review Dataset](https://archive.ics.uci.edu/ml/datasets/Drug+Review+Dataset+%28Drugs.com%29) ကို ကျွန်တော်တို့ အသုံးပြုပါမယ်။ ၎င်းမှာ ဆေးဝါးအမျိုးမျိုးနဲ့ ပတ်သက်တဲ့ လူနာ reviews တွေအပြင်၊ ကုသနေတဲ့ အခြေအနေ (condition) နဲ့ လူနာရဲ့ စိတ်ကျေနပ်မှု 10-star rating တို့ ပါဝင်ပါတယ်။

ပထမဆုံး ကျွန်တော်တို့ data ကို download လုပ်ပြီး extract လုပ်ဖို့ လိုအပ်ပါတယ်။ ဒါကို `wget` နဲ့ `unzip` commands တွေနဲ့ လုပ်ဆောင်နိုင်ပါတယ်။

```py
!wget "https://archive.ics.uci.edu/ml/machine-learning-databases/00462/drugsCom_raw.zip"
!unzip drugsCom_raw.zip
```

TSV က CSV ရဲ့ ပုံစံတစ်မျိုးဖြစ်ပြီး commas အစား tabs တွေကို separator အဖြစ် အသုံးပြုတာကြောင့်၊ ဒီ files တွေကို `csv` loading script ကို အသုံးပြုပြီး `load_dataset()` function မှာ `delimiter` argument ကို အောက်ပါအတိုင်း သတ်မှတ်ပေးခြင်းဖြင့် load လုပ်နိုင်ပါတယ်-

```py
from datasets import load_dataset

data_files = {"train": "drugsComTrain_raw.tsv", "test": "drugsComTest_raw.tsv"}
# \t က Python မှာ tab character ပါ။
drug_dataset = load_dataset("csv", data_files=data_files, delimiter="\t")
```

မည်သည့် data analysis မျိုးကိုမဆို လုပ်ဆောင်တဲ့အခါ ကောင်းမွန်တဲ့ အလေ့အကျင့်တစ်ခုကတော့ သင်အလုပ်လုပ်နေတဲ့ data အမျိုးအစားကို မြန်မြန်ဆန်ဆန် သိရှိနိုင်ဖို့ small random sample တစ်ခုကို ယူကြည့်တာပါပဲ။ 🤗 Datasets မှာ၊ `Dataset.shuffle()` နဲ့ `Dataset.select()` functions တွေကို ဆက်စပ်အသုံးပြုခြင်းဖြင့် random sample တစ်ခုကို ဖန်တီးနိုင်ပါတယ်။

```py
drug_sample = drug_dataset["train"].shuffle(seed=42).select(range(1000))
# ပထမဥပမာအချို့ကို ကြည့်ရှုပါ
drug_sample[:3]
```

```python out
{'Unnamed: 0': [87571, 178045, 80482],
 'drugName': ['Naproxen', 'Duloxetine', 'Mobic'],
 'condition': ['Gout, Acute', 'ibromyalgia', 'Inflammatory Conditions'],
 'review': ['"like the previous person mention, I&#039;m a strong believer of aleve, it works faster for my gout than the prescription meds I take. No more going to the doctor for refills.....Aleve works!"',
  '"I have taken Cymbalta for about a year and a half for fibromyalgia pain. It is great\r\nas a pain reducer and an anti-depressant, however, the side effects outweighed \r\nany benefit I got from it. I had trouble with restlessness, being tired constantly,\r\ndizziness, dry mouth, numbness and tingling in my feet, and horrible sweating. I am\r\nbeing weaned off of it now. Went from 60 mg to 30mg and now to 15 mg. I will be\r\noff completely in about a week. The fibro pain is coming back, but I would rather deal with it than the side effects."',
  '"I have been taking Mobic for over a year with no side effects other than an elevated blood pressure.  I had severe knee and ankle pain which completely went away after taking Mobic.  I attempted to stop the medication however pain returned after a few days."'],
 'rating': [9.0, 3.0, 10.0],
 'date': ['September 2, 2015', 'November 7, 2011', 'June 5, 2013'],
 'usefulCount': [36, 13, 128]}
```

reproducibility အတွက် `Dataset.shuffle()` မှာ seed ကို ကျွန်တော်တို့ သတ်မှတ်ထားတာကို သတိပြုပါ။ `Dataset.select()` က indices တွေရဲ့ iterable တစ်ခုကို မျှော်လင့်တာကြောင့်၊ shuffled dataset ကနေ ပထမ 1,000 ဥပမာတွေကို ယူဖို့ `range(1000)` ကို ကျွန်တော်တို့ ပေးပို့ခဲ့ပါတယ်။ ဒီ sample ကနေ ကျွန်တော်တို့ dataset မှာ အချို့ထူးခြားချက်တွေကို မြင်တွေ့နိုင်ပါပြီ။

*   `Unnamed: 0` column က လူနာတစ်ဦးစီအတွက် anonymized ID တစ်ခုနဲ့ သံသယဖြစ်ဖွယ် ဆင်တူပါတယ်။
*   `condition` column မှာ uppercase နဲ့ lowercase labels တွေ ရောနှောပါဝင်ပါတယ်။
*   reviews တွေက အရှည်အမျိုးမျိုးရှိပြီး Python line separators (`\r\n`) အပြင် HTML character codes (ဥပမာ `&\#039;`) တွေလည်း ပါဝင်ပါတယ်။

ဒီပြဿနာတစ်ခုစီကို ဖြေရှင်းဖို့ 🤗 Datasets ကို ဘယ်လိုအသုံးပြုရမလဲဆိုတာ ကြည့်ရအောင်။ `Unnamed: 0` column အတွက် patient ID hypothesis ကို စမ်းသပ်ဖို့၊ `Dataset.unique()` function ကို အသုံးပြုပြီး ID အရေအတွက်က split တစ်ခုစီမှာရှိတဲ့ rows အရေအတွက်နဲ့ ကိုက်ညီခြင်းရှိမရှိ စစ်ဆေးနိုင်ပါတယ်။

```py
for split in drug_dataset.keys():
    assert len(drug_dataset[split]) == len(drug_dataset[split].unique("Unnamed: 0"))
```

ဒါက ကျွန်တော်တို့ရဲ့ hypothesis ကို အတည်ပြုပုံရပါတယ်၊ ဒါကြောင့် `Unnamed: 0` column ကို နားလည်ရလွယ်ကူတဲ့ နာမည်တစ်ခုနဲ့ ပြန်လည်နာမည်ပေးခြင်းဖြင့် dataset ကို အနည်းငယ် သန့်ရှင်းရေးလုပ်ရအောင်။ `DatasetDict.rename_column()` function ကို အသုံးပြုပြီး columns တွေကို splits နှစ်ခုလုံးမှာ တစ်ပြိုင်နက်တည်း ပြန်လည်နာမည်ပေးနိုင်ပါတယ်။

```py
drug_dataset = drug_dataset.rename_column(
    original_column_name="Unnamed: 0", new_column_name="patient_id"
)
drug_dataset
```

```python out
DatasetDict({
    train: Dataset({
        features: ['patient_id', 'drugName', 'condition', 'review', 'rating', 'date', 'usefulCount'],
        num_rows: 161297
    })
    test: Dataset({
        features: ['patient_id', 'drugName', 'condition', 'review', 'rating', 'date', 'usefulCount'],
        num_rows: 53766
    })
})
```

> [!TIP]
> ✏️ **စမ်းသပ်ကြည့်ပါ။** training နဲ့ test sets တွေမှာရှိတဲ့ ထူးခြားတဲ့ ဆေးဝါးတွေနဲ့ condition တွေရဲ့ အရေအတွက်ကို ရှာဖွေဖို့ `Dataset.unique()` function ကို အသုံးပြုပါ။

ထို့နောက် `Dataset.map()` ကို အသုံးပြုပြီး `condition` labels အားလုံးကို normalize လုပ်ရအောင်။ [Chapter 3](/course/chapter3) မှာ tokenization နဲ့ လုပ်ခဲ့သလိုပဲ၊ `drug_dataset` ထဲက split တစ်ခုစီရဲ့ rows အားလုံးမှာ အသုံးပြုနိုင်မယ့် ရိုးရှင်းတဲ့ function တစ်ခုကို ကျွန်တော်တို့ သတ်မှတ်နိုင်ပါတယ်။

```py
def lowercase_condition(example):
    return {"condition": example["condition"].lower()}


drug_dataset.map(lowercase_condition)
```

```python out
AttributeError: 'NoneType' object has no attribute 'lower'
```

โอ้! map function မှာ ပြဿနာတစ်ခု ကြုံတွေ့ခဲ့ရပါပြီ။ error ကနေ `condition` column ထဲက အချို့ entries တွေဟာ `None` ဖြစ်ပြီး၊ ၎င်းတို့ဟာ strings မဟုတ်တဲ့အတွက် lowercased လုပ်လို့မရဘူးဆိုတာကို ကျွန်တော်တို့ ကောက်ချက်ချနိုင်ပါတယ်။ ဒီ rows တွေကို `Dataset.filter()` ကို အသုံးပြုပြီး ဖယ်ရှားရအောင်။ ၎င်းက `Dataset.map()` နဲ့ ဆင်တူစွာ အလုပ်လုပ်ပြီး dataset ရဲ့ single example တစ်ခုကို လက်ခံတဲ့ function တစ်ခုကို မျှော်လင့်ပါတယ်။ အောက်ပါအတိုင်း explicit function တစ်ခု ရေးမယ့်အစား...

```py
def filter_nones(x):
    return x["condition"] is not None
```

ပြီးတော့ `drug_dataset.filter(filter_nones)` ကို run မယ့်အစား၊ _lambda function_ ကို အသုံးပြုပြီး ဒါကို တစ်ကြောင်းတည်းနဲ့ လုပ်ဆောင်နိုင်ပါတယ်။ Python မှာ၊ lambda functions တွေဟာ နာမည်မပေးဘဲ သတ်မှတ်နိုင်တဲ့ small functions တွေဖြစ်ပါတယ်။ ၎င်းတို့ရဲ့ အခြေခံပုံစံက...

```
lambda <arguments> : <expression>
```

`lambda` ဟာ Python ရဲ့ special [keywords](https://docs.python.org/3/reference/lexical_analysis.html#keywords) တွေထဲက တစ်ခုဖြစ်ပြီး၊ `<arguments>` က function ရဲ့ inputs တွေကို သတ်မှတ်ပေးတဲ့ comma-separated values တွေရဲ့ list/set ဖြစ်ပြီး၊ `<expression>` က သင် execute လုပ်လိုတဲ့ operations တွေကို ကိုယ်စားပြုပါတယ်။ ဥပမာ၊ ဂဏန်းတစ်ခုကို နှစ်ထပ်ကိန်းတင်မယ့် ရိုးရှင်းတဲ့ lambda function တစ်ခုကို အောက်ပါအတိုင်း သတ်မှတ်နိုင်ပါတယ်။

```
lambda x : x * x
```

ဒီ function ကို input တစ်ခုမှာ အသုံးပြုဖို့၊ ဒါကို input နဲ့အတူ parentheses ထဲမှာ ထည့်ဖို့ လိုအပ်ပါတယ်-

```py
(lambda x: x * x)(3)
```

```python out
9
```

အလားတူပဲ၊ arguments မျိုးစုံနဲ့ lambda functions တွေကို commas တွေနဲ့ ခွဲခြားပြီး သတ်မှတ်နိုင်ပါတယ်။ ဥပမာ၊ တြိဂံတစ်ခုရဲ့ area ကို အောက်ပါအတိုင်း တွက်ချက်နိုင်ပါတယ်။

```py
(lambda base, height: 0.5 * base * height)(4, 8)
```

```python out
16.0
```

Lambda functions တွေဟာ small, single-use functions တွေ သတ်မှတ်လိုတဲ့အခါ အသုံးဝင်ပါတယ် (၎င်းတို့အကြောင်း အသေးစိတ်အချက်အလက်တွေအတွက် Andre Burgaud ရဲ့ အကောင်းဆုံး [Real Python tutorial](https://realpython.com/python-lambda/) ကို ဖတ်ရှုဖို့ ကျွန်တော်တို့ အကြံပြုပါတယ်)။ 🤗 Datasets context မှာ၊ ကျွန်တော်တို့ဟာ simple map နဲ့ filter operations တွေ သတ်မှတ်ဖို့ lambda functions တွေကို အသုံးပြုနိုင်ပါတယ်။ ဒါကြောင့် ဒီ trick ကို အသုံးပြုပြီး ကျွန်တော်တို့ dataset ထဲက `None` entries တွေကို ဖယ်ရှားရအောင်။

```py
drug_dataset = drug_dataset.filter(lambda x: x["condition"] is not None)
```

`None` entries တွေ ဖယ်ရှားပြီးတာနဲ့၊ ကျွန်တော်တို့ `condition` column ကို normalize လုပ်နိုင်ပါပြီ။

```py
drug_dataset = drug_dataset.map(lowercase_condition)
# lowercasing အလုပ်ဖြစ်ကြောင်း စစ်ဆေးပါ
drug_dataset["train"]["condition"][:3]
```

```python out
['left ventricular dysfunction', 'adhd', 'birth control']
```

အလုပ်ဖြစ်ပါတယ်! Labels တွေကို သန့်ရှင်းရေးလုပ်ပြီးတာနဲ့ reviews တွေကိုယ်တိုင် သန့်ရှင်းရေးလုပ်တာကို ကြည့်ရအောင်။

## New Columns များ ဖန်တီးခြင်း[[creating-new-columns]]

Customer reviews တွေနဲ့ အလုပ်လုပ်တဲ့အခါတိုင်း၊ review တစ်ခုစီမှာ ပါဝင်တဲ့ စကားလုံးအရေအတွက်ကို စစ်ဆေးတာဟာ ကောင်းမွန်တဲ့ အလေ့အကျင့်တစ်ခုပါပဲ။ review တစ်ခုက "Great!" လိုမျိုး စကားလုံးတစ်လုံးတည်း ဖြစ်နိုင်သလို၊ ထောင်ပေါင်းများစွာသော စကားလုံးတွေနဲ့ ပြည့်စုံတဲ့ essay တစ်ခုလည်း ဖြစ်နိုင်ပါတယ်။ use case ပေါ်မူတည်ပြီး ဒီအစွန်းရောက်အခြေအနေတွေကို ကွဲပြားစွာ ကိုင်တွယ်ဖို့ လိုအပ်ပါလိမ့်မယ်။ review တစ်ခုစီမှာရှိတဲ့ စကားလုံးအရေအတွက်ကို တွက်ချက်ဖို့၊ text တစ်ခုစီကို whitespace နဲ့ ခွဲထုတ်ခြင်းအပေါ် အခြေခံတဲ့ rough heuristic တစ်ခုကို ကျွန်တော်တို့ အသုံးပြုပါမယ်။

review တစ်ခုစီမှာရှိတဲ့ စကားလုံးအရေအတွက်ကို ရေတွက်တဲ့ ရိုးရှင်းတဲ့ function တစ်ခုကို သတ်မှတ်ရအောင်...

```py
def compute_review_length(example):
    return {"review_length": len(example["review"].split())}
```

ကျွန်တော်တို့ရဲ့ `lowercase_condition()` function နဲ့ မတူဘဲ၊ `compute_review_length()` က dataset ထဲက column names တွေထဲက တစ်ခုနဲ့ မကိုက်ညီတဲ့ key ပါဝင်တဲ့ dictionary တစ်ခုကို ပြန်ပေးပါတယ်။ ဒီကိစ္စမှာ၊ `compute_review_length()` ကို `Dataset.map()` သို့ ပေးပို့တဲ့အခါ၊ dataset ထဲက rows အားလုံးမှာ အသုံးပြုပြီး `review_length` column အသစ်တစ်ခုကို ဖန်တီးပါလိမ့်မယ်။

```py
drug_dataset = drug_dataset.map(compute_review_length)
# ပထမ training example ကို စစ်ဆေးပါ
drug_dataset["train"][0]
```

```python out
{'patient_id': 206461,
 'drugName': 'Valsartan',
 'condition': 'left ventricular dysfunction',
 'review': '"It has no side effect, I take it in combination of Bystolic 5 Mg and Fish Oil"',
 'rating': 9.0,
 'date': 'May 20, 2012',
 'usefulCount': 27,
 'review_length': 17}
```

မျှော်လင့်ထားတဲ့အတိုင်း၊ ကျွန်တော်တို့ရဲ့ training set မှာ `review_length` column တစ်ခု ထပ်ထည့်ထားတာကို မြင်တွေ့နိုင်ပါတယ်။ ဒီ column အသစ်ကို `Dataset.sort()` နဲ့ sort လုပ်ပြီး extreme values တွေ ဘယ်လိုပုံစံရှိလဲဆိုတာ ကြည့်နိုင်ပါတယ်။

```py
drug_dataset["train"].sort("review_length")[:3]
```

```python out
{'patient_id': [103488, 23627, 20558],
 'drugName': ['Loestrin 21 1 / 20', 'Chlorzoxazone', 'Nucynta'],
 'condition': ['birth control', 'muscle spasm', 'pain'],
 'review': ['"Excellent."', '"useless"', '"ok"'],
 'rating': [10.0, 1.0, 6.0],
 'date': ['November 4, 2008', 'March 24, 2017', 'August 20, 2016'],
 'usefulCount': [5, 2, 10],
 'review_length': [1, 1, 1]}
```

ကျွန်တော်တို့ သံသယရှိခဲ့တဲ့အတိုင်း၊ reviews အချို့မှာ စကားလုံးတစ်လုံးတည်းသာ ပါဝင်ပါတယ်။ ဒါက sentiment analysis အတွက် အဆင်ပြေနိုင်ပေမယ့်၊ condition ကို ခန့်မှန်းချင်တယ်ဆိုရင်တော့ အချက်အလက်မပြည့်စုံပါဘူး။

> [!TIP]
> 🙋 dataset မှာ columns အသစ်တွေ ထပ်ထည့်ဖို့ နောက်ထပ်နည်းလမ်းတစ်ခုကတော့ `Dataset.add_column()` function ကို အသုံးပြုခြင်းပါပဲ။ ဒါက column ကို Python list ဒါမှမဟုတ် NumPy array အဖြစ် ပံ့ပိုးပေးနိုင်ပြီး `Dataset.map()` က သင့် analysis အတွက် မသင့်လျော်တဲ့ အခြေအနေတွေမှာ အသုံးဝင်နိုင်ပါတယ်။

စကားလုံး ၃၀ ထက်နည်းတဲ့ reviews တွေကို ဖယ်ရှားဖို့ `Dataset.filter()` function ကို အသုံးပြုရအောင်။ `condition` column နဲ့ လုပ်ခဲ့သလိုပဲ၊ reviews တွေရဲ့ အရှည်က ဒီ threshold ထက် ပိုရှည်ဖို့ လိုအပ်ချက်ထားခြင်းဖြင့် အလွန်တိုတောင်းတဲ့ reviews တွေကို ကျွန်တော်တို့ ဖယ်ရှားနိုင်ပါတယ်။

```py
drug_dataset = drug_dataset.filter(lambda x: x["review_length"] > 30)
print(drug_dataset.num_rows)
```

```python out
{'train': 138514, 'test': 46108}
```

သင်တွေ့ရတဲ့အတိုင်း၊ ဒါက ကျွန်တော်တို့ရဲ့ မူရင်း training နဲ့ test sets တွေကနေ reviews တွေရဲ့ ၁၅% ခန့်ကို ဖယ်ရှားလိုက်တာပါပဲ။

> [!TIP]
> ✏️ **စမ်းသပ်ကြည့်ပါ။** `Dataset.sort()` function ကို အသုံးပြုပြီး စကားလုံးအရေအတွက် အများဆုံး reviews တွေကို စစ်ဆေးကြည့်ပါ။ reviews တွေကို အရှည်အလိုက် descending order နဲ့ sort လုပ်ဖို့ ဘယ် argument ကို အသုံးပြုရမလဲဆိုတာ သိရှိဖို့ [documentation](https://huggingface.co/docs/datasets/package_reference/main_classes#datasets.Dataset.sort) ကို ကြည့်ပါ။

ကျွန်တော်တို့ ကိုင်တွယ်ရမယ့် နောက်ဆုံးအရာက reviews တွေမှာ HTML character codes တွေ ပါဝင်နေခြင်းပါပဲ။ ဒီ characters တွေကို unescape လုပ်ဖို့ Python ရဲ့ `html` module ကို အောက်ပါအတိုင်း အသုံးပြုနိုင်ပါတယ်-

```py
import html

text = "I&#039;m a transformer called BERT"
html.unescape(text)
```

```python out
"I'm a transformer called BERT"
```

ကျွန်တော်တို့ corpus ထဲက HTML characters အားလုံးကို unescape လုပ်ဖို့ `Dataset.map()` ကို အသုံးပြုပါမယ်။

```python
drug_dataset = drug_dataset.map(lambda x: {"review": html.unescape(x["review"])})
```

သင်တွေ့ရတဲ့အတိုင်း၊ `Dataset.map()` method က data ကို process လုပ်ရာမှာ အတော်လေး အသုံးဝင်ပါတယ်၊ ပြီးတော့ ဒါက လုပ်ဆောင်နိုင်တဲ့အရာတွေရဲ့ အပေါ်ယံမျှသာ ရှိပါသေးတယ်!

## `map()` Method ရဲ့ အစွမ်းထက်စွမ်းရည်များ[[the-map-methods-superpowers]]

`Dataset.map()` method က `batched` argument ကို လက်ခံပါတယ်။ `True` လို့ သတ်မှတ်ရင်၊ အဲဒါက map function ကို batches အလိုက် examples တွေ ပေးပို့ပါလိမ့်မယ် (batch size ကို ပြင်ဆင်နိုင်ပေမယ့် default က ၁,၀၀၀ ဖြစ်ပါတယ်)။ ဥပမာ၊ HTML အားလုံးကို unescape လုပ်တဲ့ ယခင် map function က အလုပ်လုပ်ဖို့ အချိန်အနည်းငယ် ကြာခဲ့ပါတယ် (progress bars တွေကနေ ကြာချိန်ကို ဖတ်ရှုနိုင်ပါတယ်)။ list comprehension ကို အသုံးပြုပြီး elements အများအပြားကို တစ်ပြိုင်နက်တည်း process လုပ်ခြင်းဖြင့် ဒါကို အရှိန်မြှင့်နိုင်ပါတယ်။

`batched=True` လို့ သတ်မှတ်တဲ့အခါ function က dataset ရဲ့ fields တွေပါဝင်တဲ့ dictionary တစ်ခုကို လက်ခံပါတယ်၊ ဒါပေမယ့် value တစ်ခုစီက အခုဆိုရင် single value တစ်ခုတည်း မဟုတ်တော့ဘဲ _list of values_ ဖြစ်လာပါတယ်။ `Dataset.map()` ရဲ့ return value ကလည်း အတူတူပဲ ဖြစ်သင့်ပါတယ်- ကျွန်တော်တို့ dataset ကို update လုပ်ချင်တဲ့ ဒါမှမဟုတ် ထပ်ထည့်ချင်တဲ့ fields တွေနဲ့ list of values ပါဝင်တဲ့ dictionary တစ်ခုပါ။ ဥပမာ၊ HTML characters အားလုံးကို unescape လုပ်ဖို့ နောက်ထပ်နည်းလမ်းတစ်ခုက `batched=True` ကို အသုံးပြုခြင်းပါပဲ။

```python
new_drug_dataset = drug_dataset.map(
    lambda x: {"review": [html.unescape(o) for o in x["review"]]}, batched=True
)
```

သင်ဒီ code ကို notebook မှာ run နေတယ်ဆိုရင်၊ ဒီ command က ယခင် command ထက် အများကြီး ပိုမြန်မြန် execute ဖြစ်တာကို တွေ့ရပါလိမ့်မယ်။ ဒါဟာ ကျွန်တော်တို့ reviews တွေက HTML-unescaped ဖြစ်ပြီးသားမို့ မဟုတ်ပါဘူး၊ ယခင်အပိုင်းက instruction ( `batched=True` မပါဘဲ) ကို ပြန်လည် execute လုပ်မယ်ဆိုရင် အရင်ကအတိုင်း အချိန်တူတူ ကြာပါလိမ့်မယ်။ ဒါက list comprehensions တွေဟာ `for` loop ထဲမှာ code တူတူကို execute လုပ်တာထက် ပိုမြန်တတ်လို့ ဖြစ်ပါတယ်၊ ပြီးတော့ elements အများကြီးကို တစ်ခုချင်းစီ မဟုတ်ဘဲ တစ်ပြိုင်နက်တည်း ဝင်ရောက်ကြည့်ရှုခြင်းဖြင့် စွမ်းဆောင်ရည်အချို့ကိုလည်း ရရှိပါတယ်။

`Dataset.map()` ကို `batched=True` နဲ့ အသုံးပြုတာက [Chapter 6](/course/chapter6) မှာ ကျွန်တော်တို့ ကြုံတွေ့ရမယ့် "fast" tokenizers တွေရဲ့ မြန်နှုန်းကို ဖွင့်လှစ်ဖို့ မရှိမဖြစ်လိုအပ်ပါလိမ့်မယ်။ ၎င်းတို့က big lists of texts တွေကို မြန်မြန်ဆန်ဆန် tokenize လုပ်နိုင်ပါတယ်။ ဥပမာ၊ fast tokenizer တစ်ခုနဲ့ drug reviews အားလုံးကို tokenize လုပ်ဖို့၊ အောက်ပါ function လိုမျိုး တစ်ခုကို အသုံးပြုနိုင်ပါတယ်။

```python
from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("bert-base-cased")


def tokenize_function(examples):
    return tokenizer(examples["review"], truncation=True)
```

[Chapter 3](/course/chapter3) မှာ သင်တွေ့ခဲ့ရတဲ့အတိုင်း၊ tokenizer ကို examples တစ်ခု သို့မဟုတ် တစ်ခုထက်ပိုတာတွေကို ပေးပို့နိုင်တာကြောင့်၊ ဒီ function ကို `batched=True` ပါသည်ဖြစ်စေ၊ မပါသည်ဖြစ်စေ အသုံးပြုနိုင်ပါတယ်။ မတူညီတဲ့ options တွေရဲ့ စွမ်းဆောင်ရည်ကို နှိုင်းယှဉ်ဖို့ ဒီအခွင့်အရေးကို ယူကြရအောင်။ notebook မှာ၊ သင်တိုင်းတာချင်တဲ့ code line ရဲ့ အရှေ့မှာ `%time` ထည့်ခြင်းဖြင့် one-line instruction တစ်ခုကို အချိန်တိုင်းနိုင်ပါတယ်။

```python no-format
%time tokenized_dataset = drug_dataset.map(tokenize_function, batched=True)
```

cell တစ်ခုလုံးကို အချိန်တိုင်းဖို့အတွက် cell ရဲ့ အစမှာ `%%time` ထည့်လို့လည်း ရပါတယ်။ ကျွန်တော်တို့ run ခဲ့တဲ့ hardware မှာ၊ ဒီ instruction အတွက် 10.8s ပြသခဲ့ပါတယ် ("Wall time" နောက်မှာ ရေးထားတဲ့ နံပါတ်ပါ)။

> [!TIP]
> ✏️ **စမ်းသပ်ကြည့်ပါ။** `batched=True` ပါသည်ဖြစ်စေ၊ မပါသည်ဖြစ်စေ instruction တူတူကို execute လုပ်ကြည့်ပါ၊ ပြီးတော့ slow tokenizer နဲ့ စမ်းသပ်ကြည့်ပါ (`AutoTokenizer.from_pretrained()` method မှာ `use_fast=False` ကို ထည့်ပါ) ဒါမှ သင့် hardware မှာ ဘယ်လိုနံပါတ်တွေ ရလဲဆိုတာ မြင်နိုင်ပါလိမ့်မယ်။

batching ပါသည်ဖြစ်စေ၊ မပါသည်ဖြစ်စေ fast နဲ့ slow tokenizer တွေနဲ့ ကျွန်တော်တို့ ရရှိခဲ့တဲ့ ရလဒ်တွေကတော့ ဒီမှာပါ။

Options         | Fast tokenizer | Slow tokenizer
:--------------:|:--------------:|:-------------:
`batched=True`  | 10.8s          | 4min41s
`batched=False` | 59.2s          | 5min3s

ဒါက `batched=True` option နဲ့ fast tokenizer ကို အသုံးပြုခြင်းက batching မပါတဲ့ slow counterpart ထက် အဆ ၃၀ ပိုမြန်တယ်လို့ ဆိုလိုပါတယ် — ဒါက တကယ်ကို အံ့မခန်းပါပဲ! ဒါက `AutoTokenizer` ကို အသုံးပြုတဲ့အခါ fast tokenizers တွေ default ဖြစ်ရတဲ့ အဓိကအကြောင်းရင်းပါ (ဒါကြောင့်လည်း ၎င်းတို့ကို "fast" လို့ခေါ်တာပါ)။ ၎င်းတို့က ဒီလို speedup ကို ဘယ်လိုရရှိလဲဆိုတော့၊ နောက်ကွယ်မှာ tokenization code ကို Rust မှာ execute လုပ်ထားလို့ပါပဲ။ Rust က code execution ကို parallelize လုပ်ဖို့ လွယ်ကူစေတဲ့ ဘာသာစကားတစ်ခုပါ။

Parallelization က batching နဲ့ fast tokenizer က 6x နီးပါး speedup ရရှိရတဲ့ အကြောင်းရင်းလည်း ဖြစ်ပါတယ်- single tokenization operation တစ်ခုကို parallelize လုပ်လို့မရပါဘူး၊ ဒါပေမယ့် texts အများကြီးကို တစ်ပြိုင်နက်တည်း tokenize လုပ်ချင်တဲ့အခါ execution ကို processes အများအပြား ခွဲလိုက်ရုံပါပဲ၊ တစ်ခုစီက သူ့ရဲ့ကိုယ်ပိုင် texts တွေအတွက် တာဝန်ယူပါတယ်။

`Dataset.map()` မှာ သူ့ဘာသာသူ parallelization စွမ်းရည်အချို့လည်း ရှိပါတယ်။ ၎င်းတို့က Rust က ထောက်ပံ့ထားတာ မဟုတ်တဲ့အတွက် slow tokenizer ကို fast tokenizer နဲ့ လိုက်မီအောင် မလုပ်ပေးနိုင်ပေမယ့် (အထူးသဖြင့် fast version မရှိတဲ့ tokenizer တစ်ခုကို အသုံးပြုနေတယ်ဆိုရင်) အကူအညီဖြစ်နိုင်ပါသေးတယ်။ multiprocessing ကို ဖွင့်ဖို့အတွက်၊ `num_proc` argument ကို အသုံးပြုပြီး `Dataset.map()` ကို ခေါ်ဆိုတဲ့အခါ အသုံးပြုမယ့် processes အရေအတွက်ကို သတ်မှတ်ပေးပါ။

```py
slow_tokenizer = AutoTokenizer.from_pretrained("bert-base-cased", use_fast=False)


def slow_tokenize_function(examples):
    return slow_tokenizer(examples["review"], truncation=True)


tokenized_dataset = drug_dataset.map(slow_tokenize_function, batched=True, num_proc=8)
```

အကောင်းဆုံး processes အရေအတွက်ကို ဆုံးဖြတ်ဖို့ အချိန်တိုင်းတာနဲ့ အနည်းငယ် စမ်းသပ်ကြည့်နိုင်ပါတယ်၊ ကျွန်တော်တို့ရဲ့ ကိစ္စမှာ ၈ က အကောင်းဆုံး speed gain ကို ပေးပုံရပါတယ်။ multiprocessing ပါသည်ဖြစ်စေ၊ မပါသည်ဖြစ်စေ ကျွန်တော်တို့ ရရှိခဲ့တဲ့ နံပါတ်တွေကတော့ ဒီမှာပါ။

Options         | Fast tokenizer | Slow tokenizer
:--------------:|:--------------:|:-------------:
`batched=True`  | 10.8s          | 4min41s
`batched=False` | 59.2s          | 5min3s
`batched=True`, `num_proc=8`  | 6.52s          | 41.3s
`batched=False`, `num_proc=8` | 9.49s          | 45.2s

ဒါတွေက slow tokenizer အတွက် ပိုပြီး လက်ခံနိုင်စရာ ရလဒ်တွေပါ၊ ဒါပေမယ့် fast tokenizer ရဲ့ စွမ်းဆောင်ရည်ကလည်း သိသိသာသာ တိုးတက်လာခဲ့ပါတယ်။ သို့သော်လည်း၊ `num_proc` တန်ဖိုး ၈ ကလွဲပြီး အခြားတန်ဖိုးတွေအတွက်၊ ကျွန်တော်တို့ စမ်းသပ်မှုတွေက အဲဒီ option မပါဘဲ `batched=True` ကို အသုံးပြုတာ ပိုမြန်တယ်ဆိုတာ ပြသခဲ့တာကို သတိပြုပါ။ ယေဘုယျအားဖြင့်၊ `batched=True` နဲ့ fast tokenizers တွေအတွက် Python multiprocessing ကို အသုံးပြုဖို့ ကျွန်တော်တို့ အကြံမပြုပါဘူး။

> [!TIP]
> `num_proc` ကို အသုံးပြုပြီး သင်၏ processing ကို အရှိန်မြှင့်တင်ခြင်းက အမြဲတမ်း ကောင်းမွန်တဲ့ အကြံဥာဏ်တစ်ခုပါ၊ သင့် function က သူ့ဘာသာသူ multiprocessing မျိုးကို မလုပ်ဆောင်နေသရွေ့ပေါ့။

ဒီ functionality အားလုံးကို single method တစ်ခုတည်းမှာ ပေါင်းစပ်ထားတာက အံ့မခန်းပါပဲ၊ ဒါပေမယ့် ပိုပြီး ရှိပါသေးတယ်! `Dataset.map()` နဲ့ `batched=True` ကို အသုံးပြုပြီး သင့် dataset ထဲက elements အရေအတွက်ကို ပြောင်းလဲနိုင်ပါတယ်။ ဒါက example တစ်ခုကနေ training features များစွာ ဖန်တီးလိုတဲ့ အခြေအနေများစွာမှာ အလွန်အသုံးဝင်ပြီး၊ [Chapter 7](/course/chapter7) မှာ ကျွန်တော်တို့ လုပ်ဆောင်မယ့် NLP tasks အများအပြားအတွက် preprocessing ရဲ့ တစ်စိတ်တစ်ပိုင်းအဖြစ် ဒါကို လုပ်ဆောင်ဖို့ လိုအပ်ပါလိမ့်မယ်။

> [!TIP]
> 💡 Machine learning မှာ၊ _example_ တစ်ခုကို model ကို ကျွန်တော်တို့ ထည့်သွင်းပေးတဲ့ _features_ အစုအဝေးအဖြစ် အများအားဖြင့် သတ်မှတ်ပါတယ်။ အချို့ context တွေမှာ၊ ဒီ features တွေက `Dataset` ထဲက columns တွေရဲ့ အစုအဝေး ဖြစ်ပါလိမ့်မယ်၊ ဒါပေမယ့် အခြား context တွေမှာ (ဒီနေရာနဲ့ question answering လိုမျိုး)၊ single example တစ်ခုကနေ features များစွာကို ထုတ်ယူနိုင်ပြီး single column တစ်ခုထဲမှာ ပါဝင်နိုင်ပါတယ်။

ဒါက ဘယ်လိုအလုပ်လုပ်လဲ ကြည့်ရအောင်။ ဒီနေရာမှာ ကျွန်တော်တို့ examples တွေကို tokenize လုပ်ပြီး အရှည်ဆုံး 128 အထိ truncate လုပ်ပါမယ်၊ ဒါပေမယ့် tokenizer ကို texts တွေရဲ့ ပထမဆုံး chunk တစ်ခုတည်း မဟုတ်ဘဲ chunks အားလုံးကို ပြန်ပေးဖို့ တောင်းဆိုပါမယ်။ ဒါကို `return_overflowing_tokens=True` နဲ့ လုပ်ဆောင်နိုင်ပါတယ်။

```py
def tokenize_and_split(examples):
    return tokenizer(
        examples["review"],
        truncation=True,
        max_length=128,
        return_overflowing_tokens=True,
    )
```

`Dataset.map()` ကို dataset တစ်ခုလုံးမှာ အသုံးမပြုခင် example တစ်ခုပေါ်မှာ ဒါကို စမ်းသပ်ကြည့်ရအောင်။

```py
result = tokenize_and_split(drug_dataset["train"][0])
[len(inp) for inp in result["input_ids"]]
```

```python out
[128, 49]
```

ဒါကြောင့်၊ training set ထဲက ကျွန်တော်တို့ရဲ့ ပထမ example က features နှစ်ခု ဖြစ်လာခဲ့ပါတယ်။ ဘာလို့လဲဆိုတော့ သတ်မှတ်ထားတဲ့ maximum tokens အရေအတွက်ထက် ပိုပြီး tokenize လုပ်ခဲ့လို့ပါပဲ- ပထမတစ်ခုက အရှည် ၁၂၈၊ ဒုတိယတစ်ခုက အရှည် ၄၉ ဖြစ်ပါတယ်။ အခု dataset ရဲ့ elements အားလုံးအတွက် ဒါကို လုပ်ဆောင်ရအောင်!

```py
tokenized_dataset = drug_dataset.map(tokenize_and_split, batched=True)
```

```python out
ArrowInvalid: Column 1 named condition expected length 1463 but got length 1000
```

အိုခေ၊ ဒါအလုပ်မဖြစ်ဘူး! ဘာလို့လဲ။ error message ကို ကြည့်လိုက်ရင် ကျွန်တော်တို့ clue တစ်ခုရပါလိမ့်မယ်- columns တွေထဲက တစ်ခုရဲ့ အရှည်တွေ မကိုက်ညီပါဘူး၊ တစ်ခုက ၁,၄၆၃၊ နောက်တစ်ခုက ၁,၀၀၀ ဖြစ်ပါတယ်။ `Dataset.map()` [documentation](https://huggingface.co/docs/datasets/package_reference/main_classes#datasets.Dataset.map) ကို သင်ကြည့်ခဲ့မယ်ဆိုရင်၊ ဒါက ကျွန်တော်တို့ map လုပ်နေတဲ့ function ကို ပေးပို့လိုက်တဲ့ samples အရေအတွက်ဖြစ်တယ်ဆိုတာ သင်မှတ်မိနိုင်ပါလိမ့်မယ်။ ဒီနေရာမှာ အဲဒီ ၁,၀၀၀ examples က features အသစ် ၁,၄၆၃ ခုကို ပေးခဲ့တာကြောင့် shape error ဖြစ်သွားတာပါပဲ။

ပြဿနာကတော့ မတူညီတဲ့ datasets နှစ်ခုကို မတူညီတဲ့ sizes တွေနဲ့ ရောနှောဖို့ ကြိုးစားနေတာပါပဲ- `drug_dataset` columns တွေမှာ သတ်မှတ်ထားတဲ့ အရေအတွက်ရှိတဲ့ examples တွေ ပါဝင်မှာပါ (ကျွန်တော်တို့ error မှာပါတဲ့ ၁,၀၀၀)၊ ဒါပေမယ့် ကျွန်တော်တို့ တည်ဆောက်နေတဲ့ `tokenized_dataset` မှာတော့ ပိုများပါလိမ့်မယ် (error message မှာပါတဲ့ ၁,၄၆၃၊ ဒါက ၁,၀၀၀ ထက် များတာက ကျွန်တော်တို့ `return_overflowing_tokens=True` ကို အသုံးပြုပြီး ရှည်လျားတဲ့ reviews တွေကို example တစ်ခုထက် ပိုပြီး tokenize လုပ်နေလို့ပါ)။ ဒါက `Dataset` အတွက် အလုပ်မဖြစ်တဲ့အတွက်၊ ကျွန်တော်တို့ဟာ old dataset ကနေ columns တွေကို ဖယ်ရှားရပါလိမ့်မယ် ဒါမှမဟုတ် ၎င်းတို့ကို new dataset မှာရှိတဲ့ size တူတူ ဖြစ်အောင် လုပ်ရပါလိမ့်မယ်။ `remove_columns` argument နဲ့ ပထမနည်းလမ်းကို လုပ်ဆောင်နိုင်ပါတယ်။

```py
tokenized_dataset = drug_dataset.map(
    tokenize_and_split, batched=True, remove_columns=drug_dataset["train"].column_names
)
```

အခု ဒါက error မရှိဘဲ အလုပ်ဖြစ်ပါတယ်။ ကျွန်တော်တို့ရဲ့ new dataset မှာ original dataset ထက် elements တွေ အများကြီး ပိုများတယ်ဆိုတာကို lengths တွေကို နှိုင်းယှဉ်ခြင်းဖြင့် စစ်ဆေးနိုင်ပါတယ်။

```py
len(tokenized_dataset["train"]), len(drug_dataset["train"])
```

```python out
(206772, 138514)
```

မတူညီတဲ့ အရှည်ပြဿနာကို old columns တွေကို new ones တွေရဲ့ size တူတူ ဖြစ်အောင် လုပ်ခြင်းဖြင့်လည်း ဖြေရှင်းနိုင်တယ်လို့ ကျွန်တော်တို့ ပြောခဲ့ပါတယ်။ ဒါကိုလုပ်ဖို့၊ `return_overflowing_tokens=True` လို့ သတ်မှတ်တဲ့အခါ tokenizer က ပြန်ပေးတဲ့ `overflow_to_sample_mapping` field ကို ကျွန်တော်တို့ လိုအပ်ပါလိမ့်မယ်။ ဒါက new feature index ကနေ ဒါကို ထုတ်လုပ်ခဲ့တဲ့ sample ရဲ့ index ဆီကို mapping တစ်ခုကို ပေးပါတယ်။ ဒါကို အသုံးပြုပြီး၊ ကျွန်တော်တို့ original dataset မှာ ပါဝင်တဲ့ key တစ်ခုစီကို မှန်ကန်တဲ့ size ရှိတဲ့ values list တစ်ခုနဲ့ ဆက်စပ်နိုင်ပါတယ်၊ ဒါက example တစ်ခုစီရဲ့ values တွေကို features အသစ် ဘယ်နှစ်ခု ထုတ်လုပ်လဲဆိုတာနဲ့ အညီ အကြိမ်ကြိမ် ထပ်ခါတလဲလဲ လုပ်ခြင်းဖြင့်ပါ။

```py
def tokenize_and_split(examples):
    result = tokenizer(
        examples["review"],
        truncation=True,
        max_length=128,
        return_overflowing_tokens=True,
    )
    # New နှင့် old indices များကြား mapping ကို ထုတ်ယူပါ
    sample_map = result.pop("overflow_to_sample_mapping")
    for key, values in examples.items():
        result[key] = [values[i] for i in sample_map]
    return result
```

ဒါက `Dataset.map()` နဲ့ အလုပ်ဖြစ်တာကို ကျွန်တော်တို့ မြင်နိုင်ပါတယ်။ old columns တွေကို ဖယ်ရှားစရာ မလိုပါဘူး။

```py
tokenized_dataset = drug_dataset.map(tokenize_and_split, batched=True)
tokenized_dataset
```

```python out
DatasetDict({
    train: Dataset({
        features: ['attention_mask', 'condition', 'date', 'drugName', 'input_ids', 'patient_id', 'rating', 'review', 'review_length', 'token_type_ids', 'usefulCount'],
        num_rows: 206772
    })
    test: Dataset({
        features: ['attention_mask', 'condition', 'date', 'drugName', 'input_ids', 'patient_id', 'rating', 'review', 'review_length', 'token_type_ids', 'usefulCount'],
        num_rows: 68876
    })
})
```

ကျွန်တော်တို့ ယခင်ကနဲ့ တူညီတဲ့ training features အရေအတွက်ကို ရရှိပါတယ်၊ ဒါပေမယ့် ဒီနေရာမှာ old fields အားလုံးကို သိမ်းဆည်းထားပါတယ်။ သင် model ကို အသုံးပြုပြီးနောက် post-processing လုပ်ဖို့ ဒါတွေကို လိုအပ်မယ်ဆိုရင် ဒီချဉ်းကပ်မှုကို အသုံးပြုချင်ပါလိမ့်မယ်။

🤗 Datasets ကို နည်းလမ်းအမျိုးမျိုးနဲ့ dataset တစ်ခုကို preprocess လုပ်ဖို့ ဘယ်လိုအသုံးပြုရမယ်ဆိုတာကို အခု သင်မြင်တွေ့ခဲ့ရပါပြီ။ 🤗 Datasets ရဲ့ processing functions တွေက သင့် model training လိုအပ်ချက်အများစုကို ဖြည့်ဆည်းပေးနိုင်ပေမယ့်၊
ပိုမိုအားကောင်းတဲ့ features တွေဖြစ်တဲ့ `DataFrame.groupby()` ဒါမှမဟုတ် visualization အတွက် high-level APIs တွေလိုမျိုးကို ဝင်ရောက်ကြည့်ရှုဖို့ Pandas ကို ပြောင်းလဲဖို့ လိုအပ်တဲ့အခါတွေ ရှိနိုင်ပါတယ်။ ကံကောင်းစွာနဲ့ပဲ၊ 🤗 Datasets ကို Pandas, NumPy, PyTorch, TensorFlow, နဲ့ JAX လိုမျိုး libraries တွေနဲ့ အပြန်အလှန်အလုပ်လုပ်နိုင်အောင် ဒီဇိုင်းထုတ်ထားပါတယ်။ ဒါက ဘယ်လိုအလုပ်လုပ်လဲ ကြည့်ရအောင်။

## `Dataset`s မှ `DataFrame`s သို့ ပြန်လည်[[from-datasets-to-dataframes-and-back]]

<Youtube id="tfcY1067A5Q"/>

အခြား third-party libraries တွေကြား ပြောင်းလဲခြင်းကို ဖွင့်ဖို့၊ 🤗 Datasets က `Dataset.set_format()` function ကို ပံ့ပိုးပေးပါတယ်။ ဒီ function က dataset ရဲ့ _output format_ ကိုသာ ပြောင်းလဲတာဖြစ်ပြီး၊ အောက်ခံ _data format_ (Apache Arrow) ကို မထိခိုက်ဘဲ အခြား format တစ်ခုသို့ လွယ်ကူစွာ ပြောင်းလဲနိုင်ပါတယ်။ formatting က in place လုပ်ဆောင်ပါတယ်။ ဥပမာပြသရန်၊ ကျွန်တော်တို့ dataset ကို Pandas သို့ ပြောင်းလဲရအောင်...

```py
drug_dataset.set_format("pandas")
```

အခု dataset ရဲ့ elements တွေကို ဝင်ရောက်ကြည့်ရှုတဲ့အခါ dictionary အစား `pandas.DataFrame` တစ်ခုကို ကျွန်တော်တို့ ရရှိပါတယ်။

```py
drug_dataset["train"][:3]
```

<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>patient_id</th>
      <th>drugName</th>
      <th>condition</th>
      <th>review</th>
      <th>rating</th>
      <th>date</th>
      <th>usefulCount</th>
      <th>review_length</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>95260</td>
      <td>Guanfacine</td>
      <td>adhd</td>
      <td>"My son is halfway through his fourth week of Intuniv..."</td>
      <td>8.0</td>
      <td>April 27, 2010</td>
      <td>192</td>
      <td>141</td>
    </tr>
    <tr>
      <th>1</th>
      <td>92703</td>
      <td>Lybrel</td>
      <td>birth control</td>
      <td>"I used to take another oral contraceptive, which had 21 pill cycle, and was very happy- very light periods, max 5 days, no other side effects..."</td>
      <td>5.0</td>
      <td>December 14, 2009</td>
      <td>17</td>
      <td>134</td>
    </tr>
    <tr>
      <th>2</th>
      <td>138000</td>
      <td>Ortho Evra</td>
      <td>birth control</td>
      <td>"This is my first time using any form of birth control..."</td>
      <td>8.0</td>
      <td>November 3, 2015</td>
      <td>10</td>
      <td>89</td>
    </tr>
  </tbody>
</table>

`drug_dataset["train"]` ရဲ့ elements အားလုံးကို ရွေးချယ်ခြင်းဖြင့် training set တစ်ခုလုံးအတွက် `pandas.DataFrame` တစ်ခုကို ဖန်တီးရအောင်...

```py
train_df = drug_dataset["train"][:]
```

> [!TIP]
> 🚨 နောက်ကွယ်မှာ၊ `Dataset.set_format()` က dataset ရဲ့ `__getitem__()` dunder method အတွက် return format ကို ပြောင်းလဲပါတယ်။ ဒါက `"pandas"` format မှာရှိတဲ့ `Dataset` ကနေ `train_df` လိုမျိုး object အသစ်တစ်ခု ဖန်တီးချင်တဲ့အခါ၊ `pandas.DataFrame` တစ်ခုရဖို့ dataset တစ်ခုလုံးကို slice လုပ်ဖို့ လိုအပ်တယ်လို့ ဆိုလိုပါတယ်။ `drug_dataset["train"]` ရဲ့ type က output format နဲ့ မသက်ဆိုင်ဘဲ `Dataset` ဖြစ်နေတာကို သင်ကိုယ်တိုင် စစ်ဆေးနိုင်ပါတယ်။

ဒီကနေ ကျွန်တော်တို့ လိုချင်တဲ့ Pandas functionality အားလုံးကို အသုံးပြုနိုင်ပါတယ်။ ဥပမာ၊ `condition` entries တွေကြား class distribution ကို တွက်ချက်ဖို့ fancy chaining ကို လုပ်ဆောင်နိုင်ပါတယ်။

```py
frequencies = (
    train_df["condition"]
    .value_counts()
    .to_frame()
    .reset_index()
    .rename(columns={"index": "condition", "count": "frequency"})
)
frequencies.head()
```

<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>condition</th>
      <th>frequency</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>birth control</td>
      <td>27655</td>
    </tr>
    <tr>
      <th>1</th>
      <td>depression</td>
      <td>8023</td>
    </tr>
    <tr>
      <th>2</th>
      <td>acne</td>
      <td>5209</td>
    </tr>
    <tr>
      <th>3</th>
      <td>anxiety</td>
      <td>4991</td>
    </tr>
    <tr>
      <th>4</th>
      <td>pain</td>
      <td>4744</td>
    </tr>
  </tbody>
</table>


ကျွန်တော်တို့ Pandas analysis ပြီးသွားတာနဲ့၊ `Dataset.from_pandas()` function ကို အောက်ပါအတိုင်း အသုံးပြုခြင်းဖြင့် new `Dataset` object တစ်ခုကို အမြဲတမ်း ဖန်တီးနိုင်ပါတယ်။


```py
from datasets import Dataset

freq_dataset = Dataset.from_pandas(frequencies)
freq_dataset
```

```python out
Dataset({
    features: ['condition', 'frequency'],
    num_rows: 819
})
```

> [!TIP]
> ✏️ **စမ်းသပ်ကြည့်ပါ။** ဆေးဝါးတစ်ခုစီရဲ့ ပျမ်းမျှ rating ကို တွက်ချက်ပြီး ရလဒ်ကို new `Dataset` တစ်ခုမှာ သိမ်းဆည်းပါ။

ဒါက 🤗 Datasets မှာ ရရှိနိုင်တဲ့ preprocessing techniques အမျိုးမျိုးကို ကျွန်တော်တို့ရဲ့ လေ့လာမှုကို နိဂုံးချုပ်လိုက်ပါပြီ။ ဒီအပိုင်းကို အဆုံးသတ်ဖို့အတွက်၊ classifier တစ်ခုကို train လုပ်ဖို့ dataset ကို ပြင်ဆင်ဖို့ validation set တစ်ခုကို ဖန်တီးရအောင်။ ဒါကို မလုပ်ခင်၊ `drug_dataset` ရဲ့ output format ကို `"pandas"` ကနေ `"arrow"` သို့ ပြန်လည်သတ်မှတ်ပါမယ်။

```python
drug_dataset.reset_format()
```

## Validation Set တစ်ခု ဖန်တီးခြင်း[[creating-a-validation-set]]

evaluation အတွက် အသုံးပြုနိုင်မယ့် test set တစ်ခု ကျွန်တော်တို့မှာ ရှိပေမယ့်၊ development လုပ်နေစဉ် test set ကို မထိဘဲ သီးခြား validation set တစ်ခု ဖန်တီးတာက ကောင်းမွန်တဲ့ အလေ့အကျင့်တစ်ခုပါ။ validation set ပေါ်က သင့် models တွေရဲ့ စွမ်းဆောင်ရည်ကို သင်စိတ်ကျေနပ်သွားတာနဲ့၊ test set ပေါ်မှာ နောက်ဆုံး sanity check တစ်ခု လုပ်နိုင်ပါတယ်။ ဒီလုပ်ငန်းစဉ်က test set ကို overfit ဖြစ်ပြီး real-world data မှာ အဆင်မပြေတဲ့ model တစ်ခုကို deploy လုပ်မိမယ့် အန္တရာယ်ကို လျှော့ချရာမှာ ကူညီပေးပါတယ်။

🤗 Datasets က `scikit-learn` ရဲ့ နာမည်ကြီး functionality ပေါ် အခြေခံထားတဲ့ `Dataset.train_test_split()` function ကို ပံ့ပိုးပေးပါတယ်။ ကျွန်တော်တို့ရဲ့ training set ကို `train` နဲ့ `validation` splits တွေအဖြစ် ခွဲထုတ်ဖို့ ဒါကို အသုံးပြုရအောင် (reproducibility အတွက် `seed` argument ကို ကျွန်တော်တို့ သတ်မှတ်ပါတယ်)။

```py
drug_dataset_clean = drug_dataset["train"].train_test_split(train_size=0.8, seed=42)
# default "test" split ကို "validation" အဖြစ် နာမည်ပြောင်းပါ။
drug_dataset_clean["validation"] = drug_dataset_clean.pop("test")
# "test" set ကို ကျွန်တော်တို့ရဲ့ `DatasetDict` ထဲသို့ ထည့်ပါ။
drug_dataset_clean["test"] = drug_dataset["test"]
drug_dataset_clean
```

```python out
DatasetDict({
    train: Dataset({
        features: ['patient_id', 'drugName', 'condition', 'review', 'rating', 'date', 'usefulCount', 'review_length', 'review_clean'],
        num_rows: 110811
    })
    validation: Dataset({
        features: ['patient_id', 'drugName', 'condition', 'review', 'rating', 'date', 'usefulCount', 'review_length', 'review_clean'],
        num_rows: 27703
    })
    test: Dataset({
        features: ['patient_id', 'drugName', 'condition', 'review', 'rating', 'date', 'usefulCount', 'review_length', 'review_clean'],
        num_rows: 46108
    })
})
```

ကောင်းပါပြီ၊ အခုဆိုရင် models အချို့ကို train လုပ်ဖို့ အဆင်သင့်ဖြစ်နေတဲ့ dataset တစ်ခုကို ကျွန်တော်တို့ ပြင်ဆင်ထားပါပြီ။ [section 5](/course/chapter5/5) မှာ datasets တွေကို Hugging Face Hub သို့ ဘယ်လို upload လုပ်ရမလဲဆိုတာ ပြသပေးပါမယ်၊ ဒါပေမယ့် အခုတော့ သင့် local machine မှာ datasets တွေကို သိမ်းဆည်းနိုင်တဲ့ နည်းလမ်းအချို့ကို ကြည့်ခြင်းဖြင့် ကျွန်တော်တို့ရဲ့ analysis ကို နိဂုံးချုပ်ရအောင်။

## Dataset တစ်ခုကို သိမ်းဆည်းခြင်း[[saving-a-dataset]]

<Youtube id="blF9uxYcKHo"/>

🤗 Datasets က download လုပ်ထားတဲ့ dataset တိုင်းနဲ့ ၎င်းပေါ်မှာ လုပ်ဆောင်ထားတဲ့ operations တွေကို cache လုပ်ထားပေမယ့်၊ dataset တစ်ခုကို disk ထဲသို့ သိမ်းဆည်းချင်တဲ့အခါတွေ ရှိနိုင်ပါတယ် (ဥပမာ- cache ဖျက်ပစ်ခံရတဲ့အခါ)။ အောက်ပါဇယားမှာ ပြသထားတဲ့အတိုင်း၊ 🤗 Datasets က သင့် dataset ကို မတူညီတဲ့ formats တွေနဲ့ သိမ်းဆည်းဖို့ အဓိက functions သုံးခုကို ပံ့ပိုးပေးပါတယ်။

| Data format |        Function        |
| :---------: | :--------------------: |
|    Arrow    | `Dataset.save_to_disk()` |
|     CSV     |    `Dataset.to_csv()`    |
|    JSON     |   `Dataset.to_json()`    |

ဥပမာ၊ ကျွန်တော်တို့ရဲ့ သန့်ရှင်းရေးလုပ်ထားတဲ့ dataset ကို Arrow format နဲ့ သိမ်းဆည်းရအောင်။

```py
drug_dataset_clean.save_to_disk("drug-reviews")
```

ဒါက အောက်ပါ structure ပါဝင်တဲ့ directory တစ်ခုကို ဖန်တီးပါလိမ့်မယ်။

```
drug-reviews/
├── dataset_dict.json
├── test
│   ├── dataset.arrow
│   ├── dataset_info.json
│   └── state.json
├── train
│   ├── dataset.arrow
│   ├── dataset_info.json
│   ├── indices.arrow
│   └── state.json
└── validation
    ├── dataset.arrow
    ├── dataset_info.json
    ├── indices.arrow
    └── state.json
```

ဒီနေရာမှာ split တစ်ခုစီဟာ သူ့ရဲ့ကိုယ်ပိုင် *dataset.arrow* table နဲ့ *dataset_info.json* နဲ့ *state.json* ထဲက metadata အချို့နဲ့ ဆက်စပ်နေတာကို ကျွန်တော်တို့ မြင်တွေ့နိုင်ပါတယ်။ Arrow format ကို columns တွေနဲ့ rows တွေပါဝင်တဲ့ fancy table တစ်ခုအဖြစ် တွေးကြည့်နိုင်ပြီး ကြီးမားတဲ့ datasets တွေကို process လုပ်ပြီး သယ်ယူပို့ဆောင်တဲ့ high-performance applications တွေ တည်ဆောက်ဖို့အတွက် optimization လုပ်ထားပါတယ်။

dataset ကို သိမ်းဆည်းပြီးတာနဲ့၊ `load_from_disk()` function ကို အောက်ပါအတိုင်း အသုံးပြုပြီး load လုပ်နိုင်ပါတယ်။

```py
from datasets import load_from_disk

drug_dataset_reloaded = load_from_disk("drug-reviews")
drug_dataset_reloaded
```

```python out
DatasetDict({
    train: Dataset({
        features: ['patient_id', 'drugName', 'condition', 'review', 'rating', 'date', 'usefulCount', 'review_length'],
        num_rows: 110811
    })
    validation: Dataset({
        features: ['patient_id', 'drugName', 'condition', 'review', 'rating', 'date', 'usefulCount', 'review_length'],
        num_rows: 27703
    })
    test: Dataset({
        features: ['patient_id', 'drugName', 'condition', 'review', 'rating', 'date', 'usefulCount', 'review_length'],
        num_rows: 46108
    })
})
```

CSV နဲ့ JSON formats တွေအတွက်ကတော့၊ split တစ်ခုစီကို သီးခြား file တစ်ခုစီအဖြစ် သိမ်းဆည်းရပါမယ်။ ဒါကိုလုပ်နိုင်တဲ့ နည်းလမ်းတစ်ခုက `DatasetDict` object ထဲက keys နဲ့ values တွေကို iterate လုပ်ခြင်းပါပဲ။

```py
for split, dataset in drug_dataset_clean.items():
    dataset.to_json(f"drug-reviews-{split}.jsonl")
```

ဒါက split တစ်ခုစီကို [JSON Lines format](https://jsonlines.org) နဲ့ သိမ်းဆည်းပေးပါတယ်၊ ဒီနေရာမှာ dataset ထဲက row တစ်ခုစီကို JSON ရဲ့ single line တစ်ခုအဖြစ် သိမ်းဆည်းထားပါတယ်။ ပထမဥပမာကတော့ ဒီလိုပုံစံရှိပါတယ်။

```py
!head -n 1 drug-reviews-train.jsonl
```

```python out
{"patient_id":141780,"drugName":"Escitalopram","condition":"depression","review":"\"I seemed to experience the regular side effects of LEXAPRO, insomnia, low sex drive, sleepiness during the day. I am taking it at night because my doctor said if it made me tired to take it at night. I assumed it would and started out taking it at night. Strange dreams, some pleasant. I was diagnosed with fibromyalgia. Seems to be helping with the pain. Have had anxiety and depression in my family, and have tried quite a few other medications that haven't worked. Only have been on it for two weeks but feel more positive in my mind, want to accomplish more in my life. Hopefully the side effects will dwindle away, worth it to stick with it from hearing others responses. Great medication.\"","rating":9.0,"date":"May 29, 2011","usefulCount":10,"review_length":125}
```

အဲဒီနောက် [section 2](/course/chapter5/2) က နည်းလမ်းတွေကို အသုံးပြုပြီး JSON files တွေကို အောက်ပါအတိုင်း load လုပ်နိုင်ပါတယ်။

```py
data_files = {
    "train": "drug-reviews-train.jsonl",
    "validation": "drug-reviews-validation.jsonl",
    "test": "drug-reviews-test.jsonl",
}
drug_dataset_reloaded = load_dataset("json", data_files=data_files)
```

ဒါက 🤗 Datasets နဲ့ data wrangling ကို ကျွန်တော်တို့ရဲ့ လေ့လာမှု ပြီးဆုံးပါပြီ။ model တစ်ခုကို train လုပ်ဖို့အတွက် cleaned dataset တစ်ခု ရရှိပြီဆိုတော့၊ ဒီနေရာမှာ သင်စမ်းသပ်ကြည့်နိုင်မယ့် အကြံဥာဏ်အချို့ရှိပါတယ်။

၁။ [Chapter 3](/course/chapter3) က နည်းလမ်းတွေကို အသုံးပြုပြီး drug review ကို အခြေခံပြီး လူနာရဲ့ condition ကို ခန့်မှန်းနိုင်တဲ့ classifier တစ်ခုကို train လုပ်ပါ။
၂။ [Chapter 1](/course/chapter1) က `summarization` pipeline ကို အသုံးပြုပြီး reviews တွေရဲ့ summaries တွေကို generate လုပ်ပါ။

နောက်ထပ်အနေနဲ့၊ 🤗 Datasets က သင့် laptop ကို မပေါက်ကွဲစေဘဲ ကြီးမားတဲ့ datasets တွေနဲ့ အလုပ်လုပ်နိုင်အောင် ဘယ်လိုကူညီပေးနိုင်လဲဆိုတာ ကြည့်ရအောင်။

## ဝေါဟာရ ရှင်းလင်းချက် (Glossary)

*   **Slice and Dice**: ဒေတာအစုအဝေး (dataset) ကို လိုအပ်သလို အစိတ်စိတ်အမြွှာမြွှာ ပိုင်းဖြတ်ခြင်းနှင့် ပုံစံပြောင်းလဲခြင်း။
*   **🤗 Datasets Library**: Hugging Face က ထုတ်လုပ်ထားတဲ့ library တစ်ခုဖြစ်ပြီး AI မော်ဒယ်တွေ လေ့ကျင့်ဖို့အတွက် ဒေတာအစုအဝေး (datasets) တွေကို လွယ်လွယ်ကူကူ ဝင်ရောက်ရယူ၊ စီမံခန့်ခွဲပြီး အသုံးပြုနိုင်စေပါတယ်။
*   **Pandas**: Python programming language အတွက် data analysis နှင့် manipulation အတွက် အသုံးပြုသော open-source library။
*   **`Dataset` Object**: 🤗 Datasets library တွင် data table တစ်ခုကို ကိုယ်စားပြုသော object။
*   **`DatasetDict` Object**: Training set, validation set, နှင့် test set ကဲ့သို့သော dataset အများအပြားကို dictionary ပုံစံဖြင့် သိမ်းဆည်းထားသော object။
*   **`Dataset.map()` Method**: 🤗 Datasets library မှာ ပါဝင်တဲ့ method တစ်ခုဖြစ်ပြီး dataset ရဲ့ element တစ်ခုစီ ဒါမှမဟုတ် batch တစ်ခုစီပေါ်မှာ function တစ်ခုကို အသုံးပြုနိုင်စေသည်။
*   **UCI Machine Learning Repository**: Machine learning datasets များစွာကို စုစည်းထားသော repository တစ်ခု။
*   **Drug Review Dataset**: ဆေးဝါးများနှင့်ပတ်သက်သော လူနာသုံးသပ်ချက်များ၊ အခြေအနေများနှင့် rating များပါဝင်သော dataset။
*   **`wget` Command**: ကွန်ရက်မှ ဖိုင်များကို download လုပ်ရန်အတွက် Unix/Linux command-line utility။
*   **`unzip` Command**: ZIP archive များကို decompress လုပ်ရန်အတွက် command-line utility။
*   **TSV (Tab-Separated Values)**: Tab များဖြင့် ပိုင်းခြားထားသော ဒေတာတန်ဖိုးများပါဝင်သည့် plain text file format။
*   **CSV (Comma-Separated Values)**: ကော်မာများဖြင့် ပိုင်းခြားထားသော ဒေတာတန်ဖိုးများပါဝင်သည့် plain text file format။
*   **`delimiter` Argument**: CSV/TSV ဖိုင်များတွင် columns များကို ပိုင်းခြားရန် အသုံးပြုသော character ကို သတ်မှတ်ရန်။
*   **`load_dataset()` Function**: Hugging Face Datasets library မှ dataset များကို download လုပ်ပြီး cache လုပ်ရန် အသုံးပြုသော function။
*   **`data_files` Argument**: `load_dataset()` function တွင် dataset files (local သို့မဟုတ် remote) ၏ path (သို့မဟုတ် URL) ကို သတ်မှတ်ရန် အသုံးပြုသော argument။
*   **Random Sample**: Dataset တစ်ခုမှ ကျပန်းရွေးချယ်ထားသော အစိတ်အပိုင်းငယ်တစ်ခု။
*   **`Dataset.shuffle()`**: Dataset ရှိ examples များကို ကျပန်းရောနှောရန် (shuffle) အသုံးပြုသော function။
*   **`seed`**: ကျပန်းနံပါတ်ထုတ်လုပ်ခြင်းကို reproducibility အတွက် တည်ငြိမ်စေရန် အသုံးပြုသော တန်ဖိုး။
*   **`Dataset.select()`**: Dataset မှ သတ်မှတ်ထားသော indices များရှိ examples များကို ရွေးချယ်ရန် အသုံးပြုသော function။
*   **Indices**: Dataset အတွင်းရှိ examples များ၏ အမှတ်စဉ်နံပါတ်များ။
*   **Anonymized ID**: ပုဂ္ဂိုလ်ရေးအချက်အလက်များကို ဖုံးကွယ်ထားသော ID။
*   **Uppercase/Lowercase Labels**: စာလုံးကြီး/စာလုံးသေးဖြင့် ဖော်ပြထားသော အမျိုးအစားများ။
*   **Python Line Separators (`\r\n`)**: Python တွင် line အသစ်ပြောင်းရန် အသုံးပြုသော characters များ။
*   **HTML Character Codes (`&#039;`)**: HTML တွင် သီးခြား characters များကို ကိုယ်စားပြုသော ကုဒ်များ။
*   **`Dataset.unique()`**: Dataset column တစ်ခုရှိ ထူးခြားသော တန်ဖိုးများ (unique values) ကို ရှာဖွေရန် အသုံးပြုသော function။
*   **`DatasetDict.rename_column()`**: `DatasetDict` object အတွင်းရှိ columns များကို နာမည်ပြောင်းရန် အသုံးပြုသော function။
*   **`Dataset.filter()`**: သတ်မှတ်ထားသော condition နှင့် ကိုက်ညီသော examples များကိုသာ ရွေးချယ်ရန် အသုံးပြုသော function။
*   **Lambda Function**: Python တွင် အမည်မရှိဘဲ ရိုးရှင်းသော function တစ်ခုကို အတိုချုံးရေးသားရန် အသုံးပြုသော function။
*   **Keywords**: Python programming language တွင် အထူးအဓိပ္ပာယ်ရှိသော စကားလုံးများ။
*   **`html` Module**: Python တွင် HTML entities များကို ကိုင်တွယ်ရန် အသုံးပြုသော module။
*   **`html.unescape()`**: HTML character codes များကို ၎င်းတို့၏ မူရင်း characters များသို့ ပြန်ပြောင်းပေးသော function။
*   **Heuristic**: ပြဿနာဖြေရှင်းခြင်းအတွက် မြန်ဆန်ပြီး လက်တွေ့ကျသော နည်းလမ်း။
*   **Whitespace**: စာသားအတွင်းရှိ အဖြူနေရာများ (space, tab, newline)။
*   **`Dataset.add_column()`**: Dataset သို့ column အသစ်တစ်ခု ထည့်ရန် အသုံးပြုသော function။
*   **NumPy Array**: Python တွင် ဂဏန်းများကို ထိရောက်စွာ ကိုင်တွယ်ရန် အသုံးပြုသော multi-dimensional array object။
*   **Descending Order**: အကြီးဆုံးမှ အငယ်ဆုံးသို့ စီစဉ်ထားသော အစီအစဉ်။
*   **`batched=True`**: `Dataset.map()` function တွင် examples များကို batch အလိုက် လုပ်ဆောင်ရန် သတ်မှတ်သော argument။
*   **List Comprehension**: Python တွင် list အသစ်တစ်ခုကို တိုတိုရှင်းရှင်း ဖန်တီးရန် နည်းလမ်း။
*   **`%time` / `%%time`**: IPython/Jupyter Notebook တွင် code execution အချိန်ကို တိုင်းတာရန် အသုံးပြုသော magic commands များ။
*   **Wall Time**: code execution အတွက် စုစုပေါင်း ကြာချိန် (actual clock time)။
*   **Fast Tokenizer**: Hugging Face Transformers library တွင် Rust ဖြင့် အကောင်အထည်ဖော်ထားပြီး မြန်ဆန်သော tokenization ကို ပံ့ပိုးပေးသော tokenizer။
*   **Slow Tokenizer**: Python ဖြင့် အကောင်အထည်ဖော်ထားပြီး fast tokenizer ထက် နှေးကွေးသော tokenizer။
*   **`AutoTokenizer`**: Hugging Face Transformers library မှာ ပါဝင်တဲ့ class တစ်ခုဖြစ်ပြီး မော်ဒယ်အမည်ကို အသုံးပြုပြီး သက်ဆိုင်ရာ tokenizer ကို အလိုအလျောက် load လုပ်ပေးသည်။
*   **`truncation=True`**: Tokenization လုပ်ငန်းစဉ်တွင် input sequence များကို အများဆုံးအရှည် (max_length) သို့ ဖြတ်တောက်ရန် သတ်မှတ်ခြင်း။
*   **`use_fast=False`**: `AutoTokenizer.from_pretrained()` တွင် fast tokenizer ကို အသုံးမပြုဘဲ slow tokenizer ကို အသုံးပြုရန် သတ်မှတ်သော argument။
*   **Rust**: System programming language တစ်ခုဖြစ်ပြီး performance မြင့်မားသော applications များ တည်ဆောက်ရာတွင် အသုံးပြုသည်။
*   **Parallelize Code Execution**: Code ကို threads သို့မဟုတ် processes များစွာဖြင့် တစ်ပြိုင်နက်တည်း run ခြင်း။
*   **Multiprocessing**: ကွန်ပျူတာ၏ CPU core များစွာကို အသုံးပြု၍ တစ်ပြိုင်နက်တည်း လုပ်ငန်းဆောင်တာများ လုပ်ဆောင်ခြင်း။
*   **`num_proc` Argument**: `Dataset.map()` function တွင် multiprocessing အတွက် အသုံးပြုမည့် processes အရေအတွက်ကို သတ်မှတ်ရန် argument။
*   **Optimal Number of Processes**: အကောင်းဆုံး စွမ်းဆောင်ရည်ကို ပေးသော processes အရေအတွက်။
*   **`return_overflowing_tokens=True`**: tokenizer ကို input text ၏ အရှည်ဆုံးအပိုင်း (chunk) တစ်ခုတည်း မဟုတ်ဘဲ အခြားအပိုင်းများ (overflowing tokens) ကိုပါ ပြန်ပေးရန် သတ်မှတ်သော argument။
*   **ArrowInvalid**: Apache Arrow library မှ ထုတ်ပေးသော error တစ်မျိုး၊ ဒေတာ structure များ မကိုက်ညီခြင်းကြောင့် ဖြစ်ပေါ်တတ်သည်။
*   **Mismatched Lengths**: ဒေတာအစုအဝေးများ သို့မဟုတ် columns များ၏ အရှည် မတူညီခြင်း။
*   **`remove_columns` Argument**: `Dataset.map()` function တွင် မလိုအပ်သော columns များကို ဖယ်ရှားရန် အသုံးပြုသော argument။
*   **`column_names` Property**: Dataset ၏ column names များကို ပြန်ပေးသော property။
*   **`overflow_to_sample_mapping` Field**: `return_overflowing_tokens=True` သတ်မှတ်ထားသည့်အခါ tokenizer မှ ပြန်ပေးသော field တစ်ခု။ ၎င်းသည် output feature တစ်ခုစီကို မူရင်း input sample နှင့် ဆက်စပ်ပေးသည်။
*   **Post-processing**: Model ၏ output များကို နောက်ဆုံးအသုံးပြုမှုအတွက် ပြင်ဆင်ခြင်း လုပ်ငန်းစဉ်။
*   **`DataFrame.groupby()`**: Pandas DataFrame တွင် ဒေတာများကို column တစ်ခု သို့မဟုတ် တစ်ခုထက်ပိုသော တန်ဖိုးများအလိုက် အုပ်စုဖွဲ့ရန် အသုံးပြုသော method။
*   **High-level APIs**: ဆော့ဖ်ဝဲလ် developer များအတွက် အသုံးပြုရလွယ်ကူပြီး abstraction အဆင့်မြင့်သော Programming Interfaces များ။
*   **Visualization**: ဒေတာများကို ဂရပ်များ သို့မဟုတ် ပုံများအဖြစ် ပြသခြင်း။
*   **NumPy**: Python programming language အတွက် ဂဏန်းများကို ထိရောက်စွာ ကိုင်တွယ်ရန် အသုံးပြုသော library။
*   **PyTorch**: Facebook (ယခု Meta) က ဖန်တီးထားတဲ့ open-source machine learning library တစ်ခုဖြစ်ပြီး deep learning မော်ဒယ်တွေ တည်ဆောက်ဖို့အတွက် အသုံးပြုပါတယ်။
*   **TensorFlow**: Google က ဖန်တီးထားတဲ့ open-source machine learning library တစ်ခုဖြစ်ပြီး deep learning မော်ဒယ်တွေ တည်ဆောက်ဖို့အတွက် အသုံးပြုပါတယ်။
*   **JAX**: Google က ဖန်တီးထားတဲ့ high-performance numerical computing library တစ်ခုဖြစ်ပြီး AI/ML သုတေသနအတွက် အသုံးပြုပါတယ်။
*   **`Dataset.set_format()` Function**: Dataset ၏ output format (ဥပမာ- "pandas", "pytorch", "numpy") ကို ပြောင်းလဲရန် အသုံးပြုသော function။
*   **Output Format**: Dataset မှ data များကို မည်သည့် format ဖြင့် ပြန်ပေးမည်ကို သတ်မှတ်ခြင်း။
*   **Underlying Data Format**: Dataset အတွင်းပိုင်းတွင် data များကို သိမ်းဆည်းထားသော မူရင်း format (Apache Arrow)။
*   **Apache Arrow**: In-memory data format တစ်ခုဖြစ်ပြီး data analytics applications တွေကြား ဒေတာဖလှယ်မှုကို မြန်ဆန်စေပြီး ထိရောက်စေသည်။
*   **`pandas.DataFrame`**: Pandas library တွင် table ပုံစံ ဒေတာများကို ကိုယ်စားပြုသော data structure။
*   **`__getitem__()` Dunder Method**: Python object တစ်ခု၏ element များကို index သို့မဟုတ် key ဖြင့် ဝင်ရောက်ကြည့်ရှုသည့်အခါ ခေါ်ဆိုသော special method။
*   **`Dataset.from_pandas()` Function**: Pandas DataFrame မှ `Dataset` object တစ်ခုကို ဖန်တီးရန် အသုံးပြုသော function။
*   **Validation Set**: Training လုပ်နေစဉ် model ၏ စွမ်းဆောင်ရည်ကို အကဲဖြတ်ရန် အသုံးပြုသော dataset အပိုင်း။
*   **Test Set**: Model ၏ နောက်ဆုံး စွမ်းဆောင်ရည်ကို တိုင်းတာရန် အသုံးပြုသော dataset အပိုင်း။
*   **Sanity Check**: စနစ် သို့မဟုတ် code က မှန်ကန်စွာ အလုပ်လုပ်ခြင်းရှိမရှိ စစ်ဆေးရန် ရိုးရှင်းသော စမ်းသပ်မှု။
*   **Overfit**: Model က training data ကို အလွန်အကျွံ သင်ယူသွားပြီး မမြင်ဘူးသေးသော data တွင် စွမ်းဆောင်ရည် ကျဆင်းခြင်း။
*   **`Dataset.train_test_split()` Function**: Dataset ကို training နှင့် testing (သို့မဟုတ် validation) splits များအဖြစ် ခွဲထုတ်ရန် အသုံးပြုသော function။ `scikit-learn` library ၏ functionality နှင့် ဆင်တူသည်။
*   **`scikit-learn`**: Python အတွက် machine learning library တစ်ခု။
*   **`train_size` Argument**: `train_test_split()` function တွင် training set ၏ အရွယ်အစား (ရာခိုင်နှုန်း) ကို သတ်မှတ်ရန်။
*   **`pop()` Method**: Dictionary မှ သတ်မှတ်ထားသော key နှင့် ၎င်း၏ value ကို ဖယ်ရှားပြီး value ကို ပြန်ပေးသော method။
*   **Classifier**: ဒေတာအချက်အလက်များကို သတ်မှတ်ထားသော အမျိုးအစားများ သို့မဟုတ် အတန်းများထဲသို့ ခွဲခြားသတ်မှတ်ရန် လေ့ကျင့်ထားသော model။
*   **Cache**: မကြာခဏ အသုံးပြုရသော ဒေတာများကို မြန်မြန်ဆန်ဆန် ဝင်ရောက်ကြည့်ရှုနိုင်ရန် သိမ်းဆည်းထားသော ယာယီသိုလှောင်ရာနေရာ။
*   **`Dataset.save_to_disk()`**: Dataset ကို Apache Arrow format ဖြင့် local disk တွင် သိမ်းဆည်းရန် အသုံးပြုသော function။
*   **`Dataset.to_csv()`**: Dataset ကို CSV format ဖြင့် local disk တွင် သိမ်းဆည်းရန် အသုံးပြုသော function။
*   **`Dataset.to_json()`**: Dataset ကို JSON format ဖြင့် local disk တွင် သိမ်းဆည်းရန် အသုံးပြုသော function။
*   **`load_from_disk()` Function**: Local disk တွင် သိမ်းဆည်းထားသော dataset ကို ပြန်လည် load လုပ်ရန် အသုံးပြုသော function။
*   **JSON Lines Format**: JSON objects များကို line တစ်ကြောင်းစီတွင် တစ်ခုစီ ထားရှိသော JSON format ၏ ပုံစံတစ်မျိုး။
*   **`summarization` Pipeline**: စာသားကို အကျဉ်းချုပ်ပေးသည့် Natural Language Processing (NLP) pipeline။
*   **Data Wrangling**: ကုန်ကြမ်းဒေတာ (raw data) များကို ပိုမိုအသုံးဝင်ပြီး သန့်ရှင်းသော ပုံစံသို့ ပြောင်းလဲရန်အတွက် လုပ်ဆောင်သော လုပ်ငန်းစဉ်များ။
*   **Laptop RAM**: Laptop ကွန်ပျူတာ၏ Random Access Memory (RAM)။